package com.sheng.project.security.webmvc.config;

import com.sheng.project.security.webmvc.property.CorsApplicationProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.lang.NonNull;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author by ls
 * @date 2023/9/8
 */
@Configuration
@EnableConfigurationProperties(CorsApplicationProperties.class)
@Profile({"cors & web", "cors & webmvc"})
public class CorsWebMvcConfig implements WebMvcConfigurer {

    private static final Logger log = LoggerFactory.getLogger(CorsWebMvcConfig.class);

    private final Environment env;

    private final CorsApplicationProperties corsProperties;

    public CorsWebMvcConfig(Environment env, CorsApplicationProperties corsProperties) {
        this.env = env;
        this.corsProperties = corsProperties;
    }

    @Override
    public void addCorsMappings(@NonNull CorsRegistry registry) {
        if (!this.env.acceptsProfiles(Profiles.of("cors"))) {
            return;
        }
        this.corsProperties.getConfigurations().forEach((k, v) -> {
            log.debug("CORS 注册表配置跨域，配置标签：{}，配置路径：{}", k, v.getAllowedPath());
            if (v.getAllowedOrigins() != null && !v.getAllowedOrigins().isEmpty()) {
                if (v.getAllowCredentials() != null && v.getAllowedHeaders() != null && v.getAllowedMethods() != null && v.getAllowedOrigins() != null) {
                    registry.addMapping(v.getAllowedPath()).allowCredentials(v.getAllowCredentials()).allowedHeaders(v.getAllowedHeaders().toArray(new String[0])).allowedMethods(v.getAllowedMethods().toArray(new String[0])).allowedOrigins(v.getAllowedOrigins().toArray(new String[0]));
                }
            }
        });
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        this.corsProperties.getConfigurations().forEach((k, v) -> {
            log.debug("基于 URL 的 CORS 配置源注册跨域配置，配置标签：{}，配置路径：{}", k, v.getAllowedPath());
            if (v.getAllowedOrigins() != null && !v.getAllowedOrigins().isEmpty()) {
                source.registerCorsConfiguration(v.getAllowedPath(), v);
            }
        });
        return source;
    }

    @Bean
    public CorsFilter corsFilter(CorsConfigurationSource corsConfigurationSource) {
        return new CorsFilter(corsConfigurationSource);
    }
}
